package com.zx.mes.hyl.rocket.mq.producer;

import com.zx.mes.hyl.rocket.mq.util.RocketUtil;
import com.zx.mes.hyl.rocket.mq.yml.RocketMqProperties;
import lombok.extern.log4j.Log4j2;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;

/**
 * 无事务 同步发送消息
 *
 * @author 华云龙
 * @date 2018-12-14
 */
@Log4j2
public class SyncProducer {

    public String getNameServer() {
        return nameServer;
    }

    /**
     * 要连接的服务器集群地址
     */
    private String nameServer = "";

    /**
     * 生产者组设置
     */
    private String producerGroupName = "";

    /**
     * 读取yml配置文件中的内容
     */
    private RocketMqProperties rocketMqProperties;

    /**
     * 持有DefaultMQProducer producer
     */
    private DefaultMQProducer producer;

    /**
     * 无参构造
     */
    public SyncProducer() {
    }

    /**
     * 带rocket mq yml config
     *
     * @param rocketMqProperties yml config
     */
    public SyncProducer(RocketMqProperties rocketMqProperties) {
        this.rocketMqProperties = rocketMqProperties;
    }

    /**
     * producer config
     *
     * @return true/false
     */
    public boolean producerConfig(String producerGroupName) {
        boolean flag = true;
        RocketMqProperties.RocketMq rocketMq = RocketUtil.checkRocketMqConfig(producerGroupName, this.getRocketMqProperties());
        if (rocketMq != null) {
            this.nameServer = rocketMq.getNameServer();
            this.producerGroupName = rocketMq.getProducerGroupName();
            this.producer = new DefaultMQProducer(this.producerGroupName);
            this.producer.setNamesrvAddr(this.getNameServer());
            /// 如果发送失败,再尝试两次
            this.producer.setRetryTimesWhenSendFailed(rocketMq.getSendRetryTimes());
        } else {
            flag = false;
        }
        return flag;
    }

    /**
     * 升级版,不需要做任何设置,直接调用此方法就可同步发送消息(推荐这样使用)
     *
     * @param producerGroupName  生产者组
     * @param rocketMqProperties rocket mq yml config
     * @return true/false
     */
    public boolean producerConfig(String producerGroupName, RocketMqProperties rocketMqProperties) {
        this.setRocketMqProperties(rocketMqProperties);
        return this.producerConfig(producerGroupName);
    }

    /**
     * 发送消息,返回尝试过后的状态,由调用方作出下一步操作的判断
     *
     * @param message message
     * @return SendResult sendResult
     */
    public SendResult sendMessage(Message message) {
        SendResult sendResult = null;
        /// 开始发送消息
        this.start();
        try {
            this.producer.send(message);
        } catch (MQClientException e) {
            e.printStackTrace();
        } catch (RemotingException e) {
            e.printStackTrace();
        } catch (MQBrokerException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return sendResult;
    }

    private void start() {
        try {
            this.producer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }

    /**
     * 向外界提供一个关闭producer的接口
     */
    public void shutdown() {
        this.producer.shutdown();
    }

    /**
     * ----------------------------------------------------------------------
     * 以下是private 的getter/setter方法
     * ----------------------------------------------------------------------
     */

    public void setProducerGroupName(String producerGroupName) {
        this.producerGroupName = producerGroupName;
    }

    public RocketMqProperties getRocketMqProperties() {
        return rocketMqProperties;
    }

    public void setRocketMqProperties(RocketMqProperties rocketMqProperties) {
        this.rocketMqProperties = rocketMqProperties;
    }

}
